package com.moli.iov.open.authentication.store;

import com.alibaba.fastjson.JSONObject;
import com.moli.iov.cache.RedisUtil;
import com.moli.iov.open.constants.Constant;
import com.moli.iov.sys.model.dto.res.ClientDetailsResDto;
import com.moli.iov.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * <p>
 *  存储token redis实现类
 * </p>
 *
 * @author zql
 * @since 2019/8/29 17:38
 */
@Slf4j
@Component
public class RedisTokenStore implements TokenStore {

  @Autowired
  private RedisUtil redisUtil;

  /**
   *
   * 存储token
   *
   * @param accessToken
   * @param clientDetailsResDto
   */
  @Override
  public void storeAccessToken(String accessToken, ClientDetailsResDto clientDetailsResDto) {
    //缓存 AppId 对应的accessToken
    redisUtil.set(getAppIdKey(clientDetailsResDto.getAppId()), accessToken, Constant.EXPIRES_IN);

    //缓存token
    redisUtil.set(getAccessTokenKey(accessToken),
        JSONObject.toJSONString(clientDetailsResDto),
        Constant.EXPIRES_IN);
  }

  /**
   *
   * 获取token
   *
   * @param appId
   * @return
   */
  @Override
  public String getAccessToken(String appId) {
    return redisUtil.get(getAppIdKey(appId));
  }

  /**
   * 校验accessToken是否存在 并返回客户端信息
   * @param accessToken
   * @return
   */
  @Override
  public ClientDetailsResDto validAccessToken(String accessToken) {
    String obj = redisUtil.get(getAccessTokenKey(accessToken));
    if(StringUtil.isBlank(obj)){
      return null;
    }

    return JSONObject.parseObject(obj, ClientDetailsResDto.class);
  }

  /**
   * 修改 accessToken
   * @param accessToken
   * @param clientDetailsResDto
   * @return
   */
  @Override
  public void modifyAccessToken(String accessToken, ClientDetailsResDto clientDetailsResDto) {
    try{
      //获取appId对应的accessToken
      String oldAccessToken = redisUtil.get(getAppIdKey(clientDetailsResDto.getAppId()));

      //删除上一个accessToken
      if(StringUtil.isNotBlank(oldAccessToken)){
        redisUtil.delete(getAccessTokenKey(oldAccessToken));
      }
    }catch(Exception e){
      log.error("修改 accessToken 异常", e);
    }

    //缓存新的token
    storeAccessToken(accessToken, clientDetailsResDto);
  }

  private String getAccessTokenKey(String accessToken){
    return Constant.ACCESS_TOKEN_KEY + accessToken;
  }

  private String getAppIdKey(String appId){
    return Constant.APPID_ACCESS_TOKEN_KEY + appId;
  }
}
